package org.lex.net.log.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStreamWriter;

import javax.swing.JPopupMenu;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.StyledDocument;

import org.lex.awt.SystemClipboard;
import org.lex.net.log.Log;
import org.lex.net.log.LogUnit;
import org.lex.swing.ActionBuilder;


public class TextPaneLog extends JTextPane implements Log {
	private static final long serialVersionUID = -706033760689776894L;
	private LogFormatter formatter = null;

	public TextPaneLog() {
		super();
		this.formatter = new SimpleLogFormatter();
		this.setEditable(false);
		this.setComponentPopupMenu(new Popup());
	}

	public Log send(Object source, Object message) {
		return this.log(Type.SEND, source, message);
	}

	public Log error(Object source, Object message) {
		return this.log(Type.ERROR, source, message);
	}

	public Log misc(Object source, Object message) {
		return this.log(Type.MISC, source, message);
	}

	public Log reply(Object source, Object message) {
		return this.log(Type.REPLY, source, message);
	}

	public Log log(Type type, Object source, Object message) {
		return this.log(new LogUnit(type, source, message));
	}

	public Log log(LogUnit unit) {
		this.appendString(formatter.format(unit), TextStyles.getStyle(unit.getType()));
		return this;
	}

	int linecount = 0;

	private void appendString(String text, AttributeSet a) {
		try {
			if (linecount > 600) {
				linecount = 0;
				this.setText("");
			}
			StyledDocument doc = this.getStyledDocument();
			doc.insertString(doc.getLength(), text, a);
			this.setCaretPosition(doc.getLength());
			linecount++;
		} catch (Exception e) {
			e.printStackTrace(System.err);
		}
	}

	private void save() {
		try {
			this.write(new OutputStreamWriter(System.err));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class Popup extends JPopupMenu {
		public Popup() {
			this.add(new ActionBuilder("Copy").setActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					SystemClipboard.setClipboardContents(TextPaneLog.this.getText());
				}
			}));
			this.add(new ActionBuilder("Save...").setActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					save();
				}
			}));
			this.addSeparator();
			this.add(new ActionBuilder("Clear").setActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					TextPaneLog.this.setText("");
				}
			}));
		}
	}
}
